home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Environments / Yerk 3.6.8 / System source / Files < prev    next >
Encoding:
Text File  |  1995-11-23  |  15.4 KB  |  536 lines  |  [TEXT/YERK]

  1. \ Files  - file object and loader
  2. \ 09/10/84  CBD Version 1.0
  3. \ 10/12/84  CBD Added loader,  Length: -> bytesRead:
  4. \ 12/14/84  cbd nested loads, no default:
  5. \  7/04/86  cdn Added HFS references
  6. \  7/13/86  cdn Moved in SFPReply
  7. \  8/15/86  rfd Skip HFS search is vRefNum supplied
  8. \  8/26/86  cdn Added classinit for File
  9. \  9/8/86   rfd added dirfind resfind etc. to speed up open
  10. \ 12/3/87    rfl fixed pileup of pathnames in hopen
  11. \ 12/3/87   rfl addef flushvol:
  12. \  9/5/88    rfl    fixed hfs?
  13. \ 12/14/88    rfl fixing data record for hfs
  14. \  5/23/90    rfl added event processing during file loading
  15. \  7/25/90    rfl fixed load so that ?pause works during +echo
  16. \  9/27/90    rfl    savesig now finds app signature
  17. \ 11/12/90    rfl recoded volname?
  18. \ 12/14/90    rfl added font change to //
  19. \ 12/29/90    rfl    mods for path now sarray object
  20. \  1/31/91    rfl    fixed saveSig to get signature, not file name; font stuff now
  21. \                here; no longer need chicago 9.
  22. \  1/26/92    rfl    fixed Savesig to use heap file object. remove: loadfile closed the file.
  23. \                This wasn't good if the file was the standalone application.
  24. \ 11/25/92    rfl    Changed Last: to look at file size instead of using $ ffffff.
  25. \ 12/11/92    rfl    pulled ftype out of file, now global; added put: for single character write
  26. \                removed antiquated words like sony, external, profile; added where:
  27. \  4/30/93    rfl    Now when saving a snapshot of the environment, you no longer
  28. \                have to worry about closing the windows. The open windows are first marked
  29. \                closed, the file is saved, then they are all marked open again
  30. \  5/10/93    rfl    shortened filinit
  31. \  5/12/93    rfl    Hopen: and orf now lock down strings because of occasional problems
  32. \                 not building search path correctly due to moving of data
  33. \  5/17/93    rfl    removed res string call from clear: filelist so yerk.rsrc not
  34. \               necessary for string
  35. \  6/04/93    rfl    modified for source documentation; sfind and screate moved from 'mod'
  36. \  6/17/93    rfl    srcCreate now replaces a filemark with no yerk words defined after it.
  37. \  1/01/94    rfl incorporated file related words from base and put into class file as methods
  38. \  6/02/94  rfl changed rename to use hrename (a20b)
  39. \ 10/26/95    rfl removed error string in orf, replaced with str 100
  40. \ 11/19/95    rfl    added filespec and INLINE
  41. \ 11/23/95    rfl    modified screate for verbose
  42.  
  43. Decimal
  44.  
  45. create inLine $ 4ed4 w, \ for inline trap calls jmp (a4)
  46.  
  47. \ ( n fcb(abs) -- )
  48. Create dirfind
  49.     popA0
  50.     popD0
  51.     $ A260 w,
  52.     pushD0
  53.     next,
  54.  
  55. : volname? { strobj -- b }
  56.     start: strobj next: strobj
  57.     IF ascii : <> ELSE false THEN ;
  58.  
  59. 0 -> quitvec    \ leave vectors in a clean state
  60. 0 -> abortvec
  61.  
  62. : (nevent1) decho IF ?pause THEN ;
  63. 'c (nevent1) vect nEvent        \ use as stub until Event is loaded
  64.  
  65. : -echo  false -> decho ;
  66. : +echo  true  -> decho ;
  67. : -curs  false -> curs  ;
  68. : +curs  true  -> curs  ;
  69.  
  70. \ ( -- T or F ) returns true if on HFS
  71. : hfs? $ 3f6 -base w@ 0> ;
  72.  
  73. 0 value path    \ is instantiated by getPtxt
  74.  
  75. \  Strip volume name & HFS paths from a file name
  76. : MFSname { addr len -- addr' len' }
  77.     len ++> addr
  78.     len 0
  79.     DO    -1 ++> addr                \ scan through string backwards
  80.         addr c@ ascii : =        \ first colon we see, we stop
  81.         IF 1 ++> addr i -> len leave THEN
  82.     LOOP
  83.     addr len
  84. ;
  85.  
  86. : UpCase true -> ucase ;
  87. : LoCase false ->  ucase ;
  88.  
  89. \ ( addr len -- pfa len t OR f )  find word for name on stack. map to uppercase
  90. \   by default, but if ucase is false, then leave text alone.
  91. : sfind here >str255 ucase
  92.     IF 1+ here c@ >uc here ELSE -base THEN latest (find) ;
  93.  
  94. \ ( addr len -- )  create a new dict name/link for name on stack
  95. : sCreate docs IF line# w, THEN        \ for source documentation
  96.     sfind
  97.     IF verbose
  98.         IF here count type type# 184 ( is redefined ) cr THEN
  99.         2drop
  100.     THEN
  101.     createHdr -4 allot ;
  102.  
  103. \ don't allow two adjacent words to be file marks...this will
  104. \ prevent a load file from being embedded in the dictionary...unless the
  105. \ loadfile begins by defining yerk words...thus a loadfile cannot do any
  106. \ defining for this to work all the time.
  107. : srcCreate ( addr len -- )            \ create a filemark entry to dictionary
  108.     docs
  109.     IF dup 31 > ?error 187
  110.         latest name> @ fileMk =        \ is the last word a filemark?
  111.         IF latest dup >line -> dp pfa lfa @ current ! THEN    \ yes, so get rid of it
  112.         LoCase
  113.         screate
  114.         fileMk , 
  115.         UpCase
  116.     ELSE 2drop
  117.     THEN ;
  118.  
  119. \ create sys 7 fileSpecification record for general purpose use
  120. :CLASS ffspec <super object
  121.  
  122.     int    vref
  123.     var    parID
  124.     64 bytes name
  125.  
  126.   :m name: { addr len -- } len addr: name c! addr addr: name 1+ len cmove ;M
  127.   :M getname: addr: name count ;M
  128.   :M refNum: get: vref ;M
  129.   :M putRefNum: put: vref ;M
  130.   :M parID: get: parID ;M
  131.  
  132. ;class
  133.  
  134. \ global filespec record
  135. ffspec aFSpec
  136.  
  137.     4 Ordered-Col    fTypes        \ list of filetypes used by all files for stdget:
  138.  
  139. :CLASS File  <Super Object
  140.  
  141.     134 Bytes        FCB            \ max MAC parameter block(108 but for hgetvinfo)
  142.     \ Standard File data
  143.     Int                Good        \ this is like a variable record
  144.     Var                fType
  145.     Int                vRefNum
  146.     Int                Version
  147.     64 Bytes        Filename    \ max size is 64
  148.  
  149.  
  150.     \ ( --)  Set the NamePtr field to the abs address of the file name field
  151.     :M  SETNAMEPTR: (abs) 144 + ^base 18 + ! ;M
  152.  
  153.     :M  CLEAR:        \ Erase a parm block
  154.         ^base  144 erase  ^base 144 + 64 blanks setNamePtr: self  ;M
  155.  
  156.     :M  CLOSE:  ^base (close)  ;M
  157.  
  158.     \ ( addr len -- )  assigns file name to fcb
  159.     :M  NAME:  clear: self ^base swap 64 min swap 144 + >str255 drop ;M
  160.  
  161.     \ ( dirid -- )  set the DirID for the fcb
  162.     :M  SETDIRID: ^base 48 + !  ;M
  163.  
  164.     \ ( -- dirid )  get the DirID for the fcb
  165.     :M  GETDIRID: ^base 48 + @  ;M
  166.  
  167.     \ ( vref# -- )  set the volRefNum for the fcb
  168.     :M  SETVREF:  ^base 22 + w! ;M
  169.  
  170.     \ ( -- vref# )  get the volRefNum for the fcb
  171.     :M  GETVREF:  ^base 22 + w@ ;M
  172.  
  173.     \ ( mode -- fCode )
  174.     :M  HOPEN: { mode \ fnam1 pathname rc -- }
  175.         path IF lock: path THEN
  176.         heap> String -> fnam1  new: fnam1
  177.         heap> String -> pathName new: pathName
  178.         addr: filename count put: fnam1
  179.         lock: fnam1
  180.         start: fnam1 path
  181.         IF  ascii : charOf: fnam1
  182.             IF drop ^base mode (open)    \ assumed to be qualified path name
  183.             ELSE
  184.                 limit: path 0
  185.                 DO i at: path put: pathname
  186.                     pathname volname? 0=  hfs? land
  187.                     IF    lock: pathname                                \ if not volume
  188.                         get: pathname name: self unlock: pathname    \ get dirid
  189.                         9 ^base +base dirfind drop
  190.                         getdirid: self
  191.                         get: fnam1 name: self
  192.                         setdirid: self
  193.                         ^base mode (open) -> rc    \ attempt to open
  194.                         rc 0= IF leave THEN        \ found it !!
  195.                     ELSE 
  196.                         pathName concat: fnam1
  197.                         lock: pathname get: pathname name: self unlock: pathname
  198.                         ^base mode  (open)  -> rc
  199.                         rc 0= IF leave THEN        \ found it !!
  200.                     THEN
  201.                 LOOP
  202.                 rc IF get: fnam1 name: self THEN
  203.                 rc    \ leave return code
  204.             THEN
  205.         ELSE
  206.             hfs? 0=        \ strip HFS paths under MFS
  207.             IF    ascii : charOf: fnam1
  208.                 IF    >R 0 -base                            \ setup for replace:
  209.                     get: fnam1 MFSname drop ptr: fnam1 R + -
  210.                     " :" drop R> 0> replace: fnam1        \ delete any path spec
  211.                     get: fnam1 addr: filename >str255 drop
  212.                 THEN
  213.             THEN
  214.             ^base mode (open)
  215.         THEN
  216.         release: fnam1 dispose> fnam1
  217.         release: pathname dispose> pathname
  218.         path IF unlock: path THEN
  219.     ;M
  220.  
  221.     \ ( -- fcode )  basic I/O operations
  222.     :M  OPEN:
  223.         ^base 22 + w@ ^base 48 + @ or
  224.         IF ^base 0 (open)
  225.         ELSE 0 Hopen: self THEN
  226.     ;M
  227.  
  228.     :M  NEW:    ^base  (make)  ;M
  229.     :M  DELETE: ^base (delete) ;M
  230.  
  231.     \ ( byteoffset -- fcode )  position relative to beginning-of-file
  232.     :M  MOVETO: ^base 1 rot (lseek)   ;M
  233.  
  234.     \ ( -- byteoffset ) current position relative to beginning-of-file
  235.     :M  WHERE: ^base 46 + @ ;M
  236.  
  237.     \ ( pos -- fcode )  set End-of-File to absolute byte position
  238.     :M  SETEOF: ^base 28 + !  ^base $ a012 (fdos) ;M
  239.  
  240.     \ ( -- fcode )  open and reset file or create new if not present
  241.     :M  CREATE: { \ volid -- fcode }
  242.         ^base 22 + w@ -> volid
  243.         open: self
  244.         -dup
  245.         IF    dup -43 =
  246.             volid ^base 22 + w!
  247.             IF    drop
  248.                 new: self -dup
  249.                 0= IF ^base 0 (open) THEN
  250.             THEN
  251.         ELSE
  252.             0 setEOF: self
  253.         THEN
  254.     ;M
  255.  
  256.     \ ( -- #bytes )  return logical eof for file currently open
  257.     :M  SIZE:  ^base $ a011 (fdos)  drop ^base 28 + @ ;M
  258.  
  259.     \ ( -- )  position to file's eof
  260.     :M  LAST:  size: self moveTo: self drop  ;M
  261.  
  262.     \ ( -- lengthRead )  return actual bytes read
  263.     :M  BYTESREAD:  ^base 40 + @ ;M
  264.  
  265.     \ ( -- fcbAddr )
  266.     :M  FCB:  ^base  ;M
  267.  
  268.     \ ( -- fcode )
  269.     :M  RESULT:  addr: fcb  16 + W@ ;M
  270.  
  271.     \ ( posMode -- )  Set position mode
  272.     :M  MODE:  ^base 44 + W!   ;M
  273.  
  274.     \ ( addr length -- fcode )
  275.     :M  READ: 0 mode: Self ^base swap rot (read)  ;M
  276.  
  277.     \ ( addr maxLen -- fcode )  Read terminating with CR
  278.     :M  READLINE:  $ 0d80 Mode: self ^base swap rot (read)  ;M
  279.  
  280.     \ ( addr length -- fcode )
  281.     :M  WRITE:  ^base  swap rot (write)  ;M
  282.  
  283.     \ ( n -- fcode )
  284.     :M  PUT: pad c! pad 1 write: self ;M
  285.  
  286.     \ ( -- )  Get name from input stream, and assign to fcb
  287.     :M  SETNAME:  word" count Name: self ;M
  288.  
  289.     \ ( -- addr len )  return filename
  290.     :M  GETNAME:  addr: fileName count   ;M
  291.  
  292.     \ ( -- )  print the filename
  293.     :M  PRINT:  getName: self  type    ;M
  294.  
  295.     \ ( drive# -- )  set default drive to drive#
  296.     :M  DRIVE:   Clear: self  setVRef: self  ^base $ a015 (fdos)
  297.         ?error 165   ;M    \ Drive change unsuccessful
  298.  
  299.     \ ( addr len -- eof )  Simulate a Yerk expect from disk
  300.     :M  EXPECT: { addr len -- }
  301.         addr len 1+ erase  addr len ReadLine: self  0=
  302.         IF  dEcho
  303.             IF  addr bytesRead: self  1+ type cr
  304.             THEN
  305.             addr bytesread: self + 1-  0 swap c!  0
  306.         ELSE  1 THEN   ;M
  307.  
  308.     \ ( -- eof )  Expect a line to the TIB
  309.     :M  QUERY:  0 -> in  Tib 128 Expect: self 1 ++> line# ;M
  310.  
  311.     \ interpret the file as a Yerk source file
  312.     \ ( -- )  name must first be set
  313.     :M  INTERPRET: { \ icurs -- } -1 -> line#
  314.         open: self  classErr" 132
  315.         getName: self
  316.         srcCreate            \ create file mark entry
  317.         curs -> icurs -curs    \ Preserve cursor status
  318.         BEGIN   nEvent
  319.                 query: self   0=
  320.         WHILE  Interpret State   0= dEcho   And
  321.             IF  ok  THEN
  322.         REPEAT  ?exec close: self drop
  323.         icurs -> curs -1 -> line#  ;M    \ Restore cursor status
  324.  
  325.      :M  FLUSHVOL: ^base $ A013 (fdos) drop ;M
  326.  
  327.     \ ( taddr tlen -- fcode )
  328.     :M  RENAME: { taddr tlen -- result }
  329.         taddr tlen str255
  330.         ^base 28 + !  ^base $ A20B (fdos) ;M    \ use hrename
  331.  
  332.     \ ( -- fcode )
  333.     :M  OPENREADONLY:
  334.         ^base 22 + w@ ^base 48 + @ or
  335.         IF ^base 1 (open)
  336.         ELSE 1 Hopen: self THEN ;M
  337.  
  338.     \ ( -- type )
  339.     :M  GETTYPE:  ^base 32 + @ ;M
  340.  
  341.     \ ( -- fcode )  fills the parameter block with file info
  342.     :M  GETFILEINFO:  ^base $ A20C (fdos)  ;M
  343.  
  344.     \ ( -- fcode )
  345.     :M  SETFILEINFO:  ^base $ A00D (fdos)  ;M    \ immed doesn't work for some reason
  346.  
  347.     \ ( ftype sig -- )  Set file type, signature
  348.     :M  SET: { ftyp sig -- }        \ Sets file type, signature - recoded file-install
  349.         getDirID: self                \ Save DirID
  350.         0 setDirID: self            \ and clear it (otherwise we'll get
  351.         getFileInfo: self  drop        \  "file not found")
  352.         sig  ^base  $ 24 +  !        \ Set signature
  353.         ftyp ^base  $ 20 +  !        \ Set type
  354.         0 setDirID: self
  355.         setFileInfo: self  drop
  356.         setDirID: self                 \ Restore DirID
  357.         flushVol: self ;M
  358.  
  359.     \ ( routine# -- bool )  call a Standard File Package routine
  360.     :M  SFPCALL:  makeInt $ a9ea Trap
  361.         get: good
  362.         IF get: vRefNum ^base 80 erase setNamePtr: self
  363.             setVref: self  True
  364.         ELSE  False
  365.         THEN     ;M
  366.  
  367.     \ ( type0 ...typeN #types -- bool )  call SFGetFile
  368.     :M  STDGET:  clear: fTypes  dup 0>
  369.         IF 0 DO add: fTypes LOOP
  370.         ELSE drop THEN
  371.         $ 640064 0 0  size: fTypes -dup 0= IF -1 THEN makeInt
  372.         ixAddr: fTypes +base 0 abs: good
  373.         2 sfpCall: self  ;M
  374.  
  375.     \ call SFPutFile - takes promp, origName strings
  376.     :M  STDPUT:  { pAddr pLen nAddr nLen -- bool }
  377.         pLen pad c! pAddr pad 1+ pLen cmove
  378.         $ 640064  pad +base  nAddr nLen str255 0 abs: good
  379.         1 sfpCall: self  ;M
  380.  
  381.     :M  MAKEFSPEC: { aFSpec -- bool }
  382.         word0 int: vrefnum 0 getname: self str255
  383.         abs: aFSpec inline <[ $ 7001 w, $ aa52 w, $ 49fa0006 , ]> next,  i->l ;M
  384.  
  385.     :M  CLASSINIT:  clear: self  ;M
  386.  
  387. ;CLASS
  388.  
  389. ' File 'c fFcb !        \ set ffcb to member of file class
  390.  
  391. \ FileList keeps a stack of open load files for nested loads.
  392. :CLASS FileList  <Super Ordered-Col
  393.  
  394.     \ release heap for the top element
  395.     :M  REMOVE:  get: size dup 0= classerr" 137
  396.         1- ^elem close: [ dup @ ] drop
  397.         dispose  -1 +: size  ;M
  398.  
  399.     \ ( -- ^file ) add a new file to the stack
  400.     :M  NEW:  heap> file  add: super   ;M
  401.  
  402.     \ interpret the top file
  403.     :M  INTERPRET:  interpret: [ last: self ]  ;M
  404.  
  405.     \ ( -- )  remove all currently open files
  406.     :M  CLEAR:  ." File stack: " cr \ type# 180 ( File stack: ) cr
  407.         get: size 0
  408.         DO print: [ last: self ] cr remove: self
  409.         LOOP  ;M
  410.  
  411.     \ ( -- )  initialize list at startup
  412.     :M  INIT:   clear: super  ;M
  413.  
  414. ;CLASS
  415.  
  416. 6 fileList loadFile
  417.  
  418. : lastLoad  last: loadFile ;
  419. 'c lastLoad vect topFile
  420.  
  421. \ ( addr len -- )  open named resource file
  422. : orf { \ fnam1 pathname RC nfcb -- }
  423.     new: loadFile name: topFile
  424.     word0 getname: topfile str255 $ a997 trap i->l -1
  425.      = IF
  426.        HFS?  path land IF
  427.         HEAP> String -> fnam1 new: fnam1
  428.         heap> string -> pathName new: pathName
  429.         getname: topfile put: fnam1 lock: fnam1
  430.         -1 -> RC
  431.         HEAP> file -> nfcb
  432.         limit: path 0 DO
  433.             i at: path put: pathname
  434.             start: fnam1 get: fnam1 add: pathname
  435.             lock: pathname get: pathname
  436.             name: nfcb 9 nfcb +base dirfind
  437.             0= IF nfcb 30 + c@ 16 and ELSE true Then  not
  438.             IF
  439.                 word0 get: pathname STR255
  440.                 $ a997 trap i->l -> RC
  441.                 LEAVE
  442.             THEN unlock: pathname
  443.         LOOP
  444.         Dispose> nfcb
  445.         release: pathname dispose> pathname
  446.         release: fnam1 dispose> fnam1
  447.     ELSE   word0 getname: topfile STR255 $ a997 trap i->l -> rc
  448.     THEN     RC -1 = ?error 100    \ can't open rsrc file
  449.   THEN   remove: loadfile
  450. ;
  451. \ ( addr len - )
  452. :F OpenResFile ORF ;F
  453.  
  454. \ used to be defined in Event
  455. \ ( val -- )  set text characteristics for current grafPort
  456. : tfont  makeint $ a887 trap ;
  457. : tFace  makeInt $ a888 trap ;
  458. : tMode  makeInt $ a889 trap ;
  459. : tSize  makeInt $ a88a trap ;
  460.  
  461. \ nesting loader. Use: // filename
  462. : // { \ lcurs -- }
  463.     curs -> lcurs -curs    \ Preserve cursor status
  464.     new: loadFile  setName: topFile
  465.     getName: topFile  3 tfont 1 tface type# 173 ( Loading: ) type 0 tface 4 tfont cr
  466.     interpret: topFile  remove: loadFile
  467.     lcurs -> curs ;        \ Restore cursor status
  468.  
  469. \ ================ Save ====================
  470.  
  471. 'type COM  CONSTANT saveType            \ file type = 'COM '
  472. \ use current application signature
  473. : saveSig { \ myFile -- }
  474.     heap> file -> myFile                \ need a file structure
  475.     $ 910 -base count name: myFile        \ get nucleus name
  476.     getFileInfo: myFile drop            \ get info
  477.     myFile 36 + @ dispose> myFile ;        \ get signature
  478.  
  479. ( -- Length of dictionary to be saved )
  480. : flen      here Begin-dp @  - ;
  481.  
  482. Forward purge    \ defined in Ovl
  483.  
  484. 0 Variable  H1 here 16 allot 16 erase
  485.  
  486. \ mark all windows closed
  487. : togWindows { flag \ theWindow -- } 0 $ a924 trap
  488.     BEGIN -base -> theWindow
  489.           theWindow $ 90 + @                \ get next window in list
  490.            flag theWindow 184 + w! ( markClosed: theWindow ) dup 0=    \ continue until no more windows
  491.     UNTIL drop ;
  492. : markWindowsClosed 0 togWindows ;
  493. : markWindowsOpen   1 togWindows ;
  494.  
  495. \ Reuse target BIN file- so as not to wrestle file from it's folde
  496. \ ( -- )  Save the user dictionary
  497. : (Save) markWindowsClosed
  498.     purge
  499.     path 0 -> path    \ temporarily zero out path
  500.     setNamePtr: ffcb
  501.     create: fFcb ?error 107
  502.     \ SAVE-HEAD
  503.         here H1 !            \ Save DP
  504.         fence H1 4+ !        \ Save FENCE
  505.         voc-link H1 8+ !    \ Save VOC-LINK
  506.         latest H1 12 + !    \ Save latest NFA
  507.         0 mode: fFcb  0 fFcb 46 + w!
  508.         H1 16 write: fFcb ?error 101
  509.     \ WRITE-DICT
  510.         $ 10 fFcb $ 2E + W!
  511.         begin-dp @ flen write: fFcb ?error 105
  512.     saveType saveSig set: fFcb
  513.     close: fFcb drop
  514.     -> path            \ restore path
  515.     markWindowsOpen ;
  516.  
  517. \ Save command takes name from input stream
  518. : Save
  519.     setName: fFcb (save) ;
  520.  
  521. \ when // executes, it adds a new file object on the heap to a
  522. \ stack of files. This permits embedded loads, providing hierarchical
  523. \ nesting of source files.
  524.  
  525. : cleanUp  [Compile] ;class  clear: loadFile  init8  parmlist -1 -> line# ;
  526. : filinit   ' File 'c fFcb !  init: loadFile ;
  527.  
  528. 'c filinit -> objinit
  529. 'c cleanUp -> abortvec
  530.  
  531. 'type TEXT constant txType
  532.  
  533. \ true -> docs
  534.  
  535. // tool.load
  536.